#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/un.h>

#include <unistd.h>
#include <string.h>

#define SOCK_PATH "/tmp/my.sock"

int main(int argc, char const *argv[])
{
    // 1. 创建socket套接字
    int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sfd == -1){
        perror("socket");
        return -1;
    }

    printf("--socket(%d) ok--\n", sfd);

    // 2. 绑定本地文件
    struct sockaddr_un uaddr = { AF_UNIX, SOCK_PATH};
    int ret = bind(sfd, (struct sockaddr *)&uaddr, sizeof(uaddr));
    if(ret != 0){
        perror("bind");
        close(sfd);
        return -1;
    }
    printf("bind(%s) OK\n", SOCK_PATH);


    // 3. 监听
    listen(sfd, 1);
      // 4. 等待连接
    int cfd = accept(sfd, NULL, NULL);  // 阻塞
    printf("---其它本地进程已连接---\n");  // 想获取进程信息 fcntl(cfd, FD_STAT, &i);
    
    char buf[128] = ""; // 缓冲区
    // 子进程负责收
    if(fork() == 0){
        close(sfd); // socket创建时的套接字
        while(1){
            bzero(buf, 128);
            read(cfd, buf, 128); // 接收
            printf("B: %s \n", buf);
            if(strncmp(buf, "exit", 4) == 0) break;
        }
        close(cfd);
        _exit(0);
    }
    
    // 父进程：负责发送数据
    while(1){
        bzero(buf, 128);
        fgets(buf, 128, stdin);
        buf[strlen(buf)-1] = 0;
        write(cfd, buf, strlen(buf)); // 回应
        if(strncmp(buf, "exit", 4) == 0) break;
    }
    wait(NULL);
    close(cfd);
    close(sfd);
    // 删除sock文件
    unlink(SOCK_PATH);

    return 0;
}
